/**
* Annotations is a representations of the annotation file as well as a wrapper 
* for the xforms-elements of the gui.
*/ 
var Annotations = Class.create();
Annotations.prototype = {
	initialize: function(annotationFileEditor) {
		this.annotationFileEditor = annotationFileEditor;
		this.cElements = new Hash();
    
	},
	/** NOT FINISHED!
	 * Reads the xml of the annotationfile and the default xform 
	 * and builds the internal tree of Annotations and elements. 
	 * Will also wrap the xform-elements and tie the edit-functionality to it. 
   * @param {Node} annotationsRoot Root of xml of annotationfile.
   * @param {Node} documentRoot Root of xhtml-document with xform in it. 
   */
	load: function(AnnotationsRoot, documentRoot) {
		var anne = AnnotationsRoot.childNodes;
		for (var i=0,child; child = anne[i++];) {
			if (child.nodeName == 'core-component') 
				this.addCoreComponent(child);
		}
	},
	/** NOT FINISHED!
	* Adds the annotations from the file to a CElement.
	* adds a CElement of it doesn't exist yet. 
	*/
	addAnnotations: function(node) {
		var ce = new CElement(node.getAttribute('den'));
		ce.properties = node;
		this.cElements['ce.ccn'] = ce;
		
	},
	/**
	 * Exports the current Annotations to the annotationfile-format.
	 * @return {Node} The root node of the document to save to the annotation file. 
	 */
	file: function() {
		return "<annotations></annotations>";
	}
	 
};

/**
* Base element for the core components in the Annotations-class.
* Has some static variables to use in creating the gui and per object
* has the annotation-properties, the CCN and possibly a reference to 
* a GUI-element(only if there is an xforms-element with the exact same CCN).
*/ 
var CElement = Class.create();
/**
* For CElement and each subclass an array of PropertiesForms. 
* So CElement.propertiesForms['FormElement'][0] is one PropertiesForm. 
* key is classname. 
*/
CElement.propertiesForms = new Hash({});
/**
* For CElement and each subclass an array of eventlisteners. 
* key is classname. 
* So CElement.eventListeners['GroupElement'][0] is one eventListener.
*/
CElement.eventListeners = new Hash({});
/**
* A reference to the superclass of this class.
* @desdec Can't get a reference without this explicit one without using eval. 
*/
CElement.parentClass = null;


CElement.prototype = {
  /** {CElement} Reference to the class of this object, needed to access statics */ 
	cclass: CElement,
	/** {String} Full Core Component Name */
	ccn: null,
	/** {Node} reference to the gui-element, that is wrapped by this object. */
	guiElement: null,
	/** {Node} Annotations for this element */
	properties: null,
	/**
	* @constructor
	* @param {String} ccn Name of CoreComponent this element represents. 
	* @param {element} formelement The DOM element which this object wraps.
	*/
	initialize: function(ccn, guiElement) {
		this.guiElement = guiElement;
	},
	/** Add a propertiesForm to the class of this object. */ 
	addPropertiesForm: function(form) {
		if (!CElement.propertiesForms[getClassName(this)]) {
			CElement.propertiesForms[getClassName(this)] = new Array();
		}
	  CElement.propertiesForms[getClassName(this)].push(form);
	},
	/** Return an Array of all PropertiesForms of the class of this object and
	* all superClasses. */
	listPropertiesForms: function() {
		// return all properties of this.class and this.parentClass ...
	},
	/** Add an EventListener to the class of this object. */
	addEventListener: function() {
		// add event listener to class
	},
	/** List all eventListener of the class of this object and all superclasses. */
	listEventListeners: function() {
	  // list listeners in class
	},
	/** Get a reference to the superClass of the class of this object. */
	getParentClass: function() {
		return this.cclass.parentClass;
	}
};

/** A CEElement of a AggregateCoreComponent */
var GroupElement = Class.create();
GroupElement.parentClass = CElement;
GroupElement.prototype = Object.extend(new CElement(), {
	cclass: GroupElement,
	initialize: function() {}
});

/** Class that holds the informatie for an eventListener.
* Used to add evenListeners to CElements, that are applied to 
* all guiElements of all objects of that class. */
var CEventListener = Class.create();
CEventListener.prototype = {
	/** @constructor
	* same interface as the W3C addEventListeren method */
	initialize: function (type, listener, useCapture) {
		this.type = type;
		this.listener = listener;
		if (useCapture) this.useCapture = useCapture;
	},
  type: null,
	listener: null,
	useCapture: false
}

/** Returns the classname of obj */
var getClassName = function(obj) {
    var c = Object.prototype.toString.apply(obj); 
    return c.substring(8, c.length-1);  
};
